import cv2
import numpy as np
import os
import matplotlib.pyplot as plt

# 读取图像文件
image = cv2.imread('hanzi1.jpg')

# 将图像转换为灰度图
grayscale_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 对灰度图进行全域阈值处理转化为二值图像，并打印转化后的图像
threshold = 110
_, binary_image = cv2.threshold(grayscale_image, threshold, 255, cv2.THRESH_BINARY_INV)

# 创建元素结构，采用4*4的矩形元素
kernel = np.ones((3, 3), np.uint8)

# 进行腐蚀操作，迭代3次增强腐蚀效果
eroded_img = cv2.erode(binary_image, kernel, iterations=3)

dilated_img = cv2.dilate(eroded_img, kernel, iterations=2)  # 对图像进行膨胀操作

#中值滤波去除dilated_img的小白点
median_img = cv2.medianBlur(dilated_img,13)

#运用闭运算填充闭合区域
kernel3 = np.ones((7, 7), np.uint8)
closing_img = cv2.morphologyEx(median_img, cv2.MORPH_CROSS, kernel3, iterations=10)

#canney边缘识别
lower = 50
upper = 200
edges_no_blur = cv2.Canny(closing_img, lower, upper)

img_blur = cv2.GaussianBlur(closing_img,(3,3), 0) #高斯滤波
edges_with_blur = cv2.Canny(img_blur, lower, upper)

#提取轮廓
contours, _ = cv2.findContours(edges_with_blur, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 创建字符图像保存目录
chars_dir = 'chars'
if not os.path.exists(chars_dir):
    os.makedirs(chars_dir)

count = 1
for contour in contours:
    # 计算轮廓周长
    perimeter = cv2.arcLength(contour, True)
    print("轮廓周长：", perimeter)

    if perimeter > 600:
        # 获取轮廓的边界矩形
        x, y, w, h = cv2.boundingRect(contour)

        # 在原图上画出矩形
        cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 5)

        # 提取并保存字符图像
        char_img = image[y:y + h, x:x + w]
        char_filename = os.path.join(chars_dir, f'{count}.png')
        cv2.imwrite(char_filename, char_img)
        count += 1


# 创建画布
fig, axs = plt.subplots(2, 4,figsize=(15, 10))

# 在画布上显示图像

axs[0,0].imshow(grayscale_image, cmap='gray')
axs[0,0].set_title('Grayscale Image')

axs[0,1].imshow(binary_image, cmap='gray')
axs[0,1].set_title('Binary Image')

axs[0,2].imshow(eroded_img, cmap='gray')
axs[0,2].set_title('Eroded Image')

axs[0,3].imshow(median_img, cmap='gray')
axs[0,3].set_title('Median Image')

axs[1,0].imshow(closing_img, cmap='gray')
axs[1,0].set_title('Eclosing Img')

axs[1,1].imshow(edges_with_blur, cmap='gray')
axs[1,1].set_title('Edges with Blur')

axs[1,2].imshow(image, cmap='gray')
axs[1,2].set_title('bounding box')

# 隐藏坐标轴
for ax in axs.flat:
    ax.axis('off')

# 调整子图之间的间距
plt.tight_layout(pad=1)

# 显示画布
plt.show()
